/*
* Blas.cs
*
* BLAS provider for AMD Acml.
*
* Copyright (c) 2005, dnAnalytics. All rights reserved.
*/
using dnAnalytics.LinearAlgebra.Native;
using dnAnalytics.Math;

namespace dnAnalytics.LinearAlgebra.Native.Acml
{
    internal sealed class Blas : IBlas
    {
        private static readonly IBlas instance = new Blas();

        private Blas() { }

        #region Public Members

        public static IBlas Instance
        {
            get { return instance; }
        }

        public double Ddot(int n, double[] x, int incX, double[] y, int incY)
        {
            return SafeNativeMethods.ddot(n, x, incX, y, incY);
        }

        public Complex Zdotu_sub(int n, Complex[] x, int incX, Complex[] y, int incY)
        {
            Complex dotu = SafeNativeMethods.zdotu(n, x, incX, y, incY);
            return dotu;
        }

        public Complex Zdotc_sub(int n, Complex[] x, int incX, Complex[] y, int incY)
        {
            Complex dotc = SafeNativeMethods.zdotc(n, x, incX, y, incY);
            return dotc;
        }

        public double Dnrm2(int n, double[] x, int incX)
        {
            return SafeNativeMethods.dnrm2(n, x, incX);
        }

        public double Dasum(int n, double[] x, int incX)
        {
            return SafeNativeMethods.dasum(n, x, incX);
        }

        public double Dznrm2(int n, Complex[] x, int incX)
        {
            return SafeNativeMethods.dznrm2(n, x, incX);
        }

        public double Dzasum(int n, Complex[] x, int incX)
        {
            return SafeNativeMethods.dzasum(n, x, incX);
        }

        public int Idamax(int n, double[] x, int incX)
        {
            return SafeNativeMethods.idamax(n, x, incX) - 1;
        }

        public int Izamax(int n, Complex[] x, int incX)
        {
            return SafeNativeMethods.izamax(n, x, incX) - 1;
        }

        public void Dswap(int n, double[] x, int incX, double[] y, int incY)
        {
            SafeNativeMethods.dswap(n, x, incX, y, incY);
        }

        public void Dcopy(int n, double[] x, int incX, double[] y, int incY)
        {
            SafeNativeMethods.dcopy(n, x, incX, y, incY);
        }

        public void Daxpy(int n, double alpha, double[] x, int incX, double[] y, int incY)
        {
            SafeNativeMethods.daxpy(n, alpha, x, incX, y, incY);
        }

        public void Drotg(ref double a, ref double b, out double c, out double s)
        {
            SafeNativeMethods.drotg(ref a, ref b, out c, out s);
        }

        public void Zswap(int n, Complex[] x, int incX, Complex[] y, int incY)
        {
            SafeNativeMethods.zswap(n, x, incX, y, incY);
        }

        public void Zcopy(int n, Complex[] x, int incX, Complex[] y, int incY)
        {
            SafeNativeMethods.zcopy(n, x, incX, y, incY);
        }

        public void Zaxpy(int n, Complex alpha, Complex[] x, int incX, Complex[] y, int incY)
        {
            SafeNativeMethods.zaxpy(n, ref alpha, x, incX, y, incY);
        }

        public void Zrotg(ref Complex a, ref Complex b, out Complex c, out Complex s)
        {
            SafeNativeMethods.zrotg(ref a, ref b, out c, out s);
        }

        public void Drotmg(ref double d1, ref double d2, ref double x1, double y1, out double[] p)
        {
            p = new double[5];
            SafeNativeMethods.drotmg(d1, d2, x1, y1, p);
        }

        public void Drot(int n, double[] x, int incX, double[] y, int incY, double c, double s)
        {
            SafeNativeMethods.drot(n, x, incX, y, incY, c, s);
        }

        public void Drotm(int n, double[] x, int incX, double[] y, int incY, double[] p)
        {
            SafeNativeMethods.drotm(n, x, incX, y, incY, p);
        }

        public void Zdrot(int n, Complex[] x, int incX, Complex[] y, int incY, double c, double s)
        {
            SafeNativeMethods.zdrot(n, x, incX, y, incY, c, s);
        }

        public void Dscal(int n, double alpha, double[] x, int incX)
        {
            SafeNativeMethods.dscal(n, alpha, x, incX);
        }

        public void Zscal(int n, Complex alpha, Complex[] x, int incX)
        {
            SafeNativeMethods.zscal(n, ref alpha, x, incX);
        }

        public void Zdscal(int n, double alpha, Complex[] x, int incX)
        {
            SafeNativeMethods.zdscal(n, alpha, x, incX);
        }

        public void Dgemv(BlasOrderType order, BlasTransType transA, int m, int n, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }
            SafeNativeMethods.dgemv(tranA, m, n, alpha, a, lda, x, incX, beta, y, incY);
        }

        public void Dgbmv(BlasOrderType order, BlasTransType transA, int m, int n, int kl, int ku, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }
            SafeNativeMethods.dgbmv(tranA, m, n, kl, ku, alpha, a, lda, x, incX, beta, y, incY);
        }

        public void Dtrmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] a, int lda, double[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.dtrmv(cuplo, tranA, cdiag, n, a, lda, x, incX);
        }

        public void Dtbmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, double[] a, int lda, double[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.dtbmv(cuplo, tranA, cdiag, n, k, a, lda, x, incX);
        }

        public void Dtpmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] ap, double[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.dtpmv(cuplo, tranA, cdiag, n, ap, x, incX);
        }

        public void Dtrsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] a, int lda, double[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.dtrsv(cuplo, tranA, cdiag, n, a, lda, x, incX);
        }

        public void Dtbsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, double[] a, int lda, double[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.dtbsv(cuplo, tranA, cdiag, n, k, a, lda, x, incX);
        }

        public void Dtpsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] ap, double[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.dtpsv(cuplo, tranA, cdiag, n, ap, x, incX);
        }

        public void Zgemv(BlasOrderType order, BlasTransType transA, int m, int n, Complex alpha, Complex[] a, int lda, Complex[] x, int incX, Complex beta, Complex[] y, int incY)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }
            SafeNativeMethods.zgemv(tranA, m, n, ref alpha, a, lda, x, incX, ref beta, y, incY);
        }


        public void Zgbmv(BlasOrderType order, BlasTransType transA, int m, int n, int kl, int ku, Complex alpha, Complex[] a, int lda, Complex[] x, int incX, Complex beta, Complex[] y, int incY)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }
            SafeNativeMethods.zgbmv(tranA, m, n, kl, ku, ref alpha, a, lda, x, incX, ref beta, y, incY);
        }

        public void Ztrmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, Complex[] a, int lda, Complex[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.ztrmv(cuplo, tranA, cdiag, n, a, lda, x, incX);
        }

        public void Ztbmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, Complex[] a, int lda, Complex[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.ztbmv(cuplo, tranA, cdiag, n, k, a, lda, x, incX);
        }

        public void Ztpmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, Complex[] ap, Complex[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.ztpmv(cuplo, tranA, cdiag, n, ap, x, incX);
        }

        public void Ztrsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, Complex[] a, int lda, Complex[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.ztrsv(cuplo, tranA, cdiag, n, a, lda, x, incX);
        }

        public void Ztbsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, Complex[] a, int lda, Complex[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.ztbsv(cuplo, tranA, cdiag, n, k, a, lda, x, incX);
        }

        public void Ztpsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, Complex[] ap, Complex[] x, int incX)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }
            SafeNativeMethods.ztpsv(cuplo, tranA, cdiag, n, ap, x, incX);
        }

        public void Dsymv(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dsymv(cuplo, n, alpha, a, lda, x, incX, beta, y, incY);
        }

        public void Dsbmv(BlasOrderType order, BlasUpLoType uplo, int n, int k, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dsbmv(cuplo, n, k, alpha, a, lda, x, incX, beta, y, incY);
        }

        public void Dspmv(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] ap, double[] x, int incX, double beta, double[] y, int incY)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dspmv(cuplo, n, alpha, ap, x, incX, beta, y, incY);
        }

        public void Dger(BlasOrderType order, int m, int n, double alpha, double[] x, int incX, double[] y, int incY, double[] a, int lda)
        {
            SafeNativeMethods.dger(m, n, alpha, x, incX, y, incY, a, lda);
        }

        public void Dsyr(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] a, int lda)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dsyr(cuplo, n, alpha, x, incX, a, lda);
        }

        public void Dspr(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] ap)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dspr(cuplo, n, alpha, x, incX, ap);
        }

        public void Dsyr2(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] y, int incY, double[] a, int lda)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dsyr2(cuplo, n, alpha, x, incX, y, incY, a, lda);
        }

        public void Dspr2(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] y, int incY, double[] a)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dspr2(cuplo, n, alpha, x, incX, y, incY, a);
        }

        public void Zhemv(BlasOrderType order, BlasUpLoType uplo, int n, Complex alpha, Complex[] a, int lda, Complex[] x, int incX, Complex beta, Complex[] y, int incY)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zhemv(cuplo, n, ref alpha, a, lda, x, incX, ref beta, y, incY);
        }

        public void Zhbmv(BlasOrderType order, BlasUpLoType uplo, int n, int k, Complex alpha, Complex[] a, int lda, Complex[] x, int incX, Complex beta, Complex[] y, int incY)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zhbmv(cuplo, n, k, ref alpha, a, lda, x, incX, ref beta, y, incY);
        }

        public void Zhpmv(BlasOrderType order, BlasUpLoType uplo, int n, Complex alpha, Complex[] ap, Complex[] x, int incX, Complex beta, Complex[] y, int incY)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zhpmv(cuplo, n, ref alpha, ap, x, incX, ref beta, y, incY);
        }

        public void Zgeru(BlasOrderType order, int m, int n, Complex alpha, Complex[] x, int incX, Complex[] y, int incY, Complex[] a, int lda)
        {
            SafeNativeMethods.zgeru(m, n, ref alpha, x, incX, y, incY, a, lda);
        }

        public void Zgerc(BlasOrderType order, int m, int n, Complex alpha, Complex[] x, int incX, Complex[] y, int incY, Complex[] a, int lda)
        {
            SafeNativeMethods.zgerc(m, n, ref alpha, x, incX, y, incY, a, lda);
        }

        public void Zher(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, Complex[] x, int incX, Complex[] a, int lda)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zher(cuplo, n, alpha, x, incX, a, lda);
        }

        public void Zhpr(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, Complex[] x, int incX, Complex[] a)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zhpr(cuplo, n, alpha, x, incX, a);
        }

        public void Zher2(BlasOrderType order, BlasUpLoType uplo, int n, Complex alpha, Complex[] x, int incX, Complex[] y, int incY, Complex[] a, int lda)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zher2(cuplo, n, ref alpha, x, incX, y, incY, a, lda);
        }

        public void Zhpr2(BlasOrderType order, BlasUpLoType uplo, int n, Complex alpha, Complex[] x, int incX, Complex[] y, int incY, Complex[] ap)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zhpr2(cuplo, n, ref alpha, x, incX, y, incY, ap);
        }

        public void Dgemm(BlasOrderType order, BlasTransType transA, BlasTransType transB, int m, int n, int k, double alpha, double[] a, int lda, double[] b, int ldb, double beta, double[] c, int ldc)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char tranB = 'N';
            if (transB == BlasTransType.Trans)
            {
                tranB = 'T';
            }
            else if (transB == BlasTransType.ConjTrans)
            {
                tranB = 'C';
            }
            SafeNativeMethods.dgemm(tranA, tranB, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
        }

        public void Dsymm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb, double beta, double[] c, int ldc)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cside = 'L';
            if (side == BlasSideType.Right)
            {
                cside = 'R';
            }
            SafeNativeMethods.dsymm(cside, cuplo, m, n, alpha, a, lda, b, ldb, beta, c, ldc);
        }

        public void Dsyrk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, double alpha, double[] a, int lda, double beta, double[] c, int ldc)
        {
            char tran = 'N';
            if (trans == BlasTransType.Trans)
            {
                tran = 'T';
            }
            else if (trans == BlasTransType.ConjTrans)
            {
                tran = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dsyrk(cuplo, tran, n, k, alpha, a, lda, beta, c, ldc);
        }

        public void Dsyr2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, double alpha, double[] a, int lda, double[] b, int ldb, double beta, double[] c, int ldc)
        {
            char tran = 'N';
            if (trans == BlasTransType.Trans)
            {
                tran = 'T';
            }
            else if (trans == BlasTransType.ConjTrans)
            {
                tran = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.dsyr2k(cuplo, tran, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
        }

        public void Dtrmm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }

            char cside = 'L';
            if (side == BlasSideType.Right)
            {
                cside = 'R';
            }
            SafeNativeMethods.dtrmm(cside, cuplo, tranA, cdiag, m, n, alpha, a, lda, b, ldb);
        }

        public void Dtrsm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }

            char cside = 'L';
            if (side == BlasSideType.Right)
            {
                cside = 'R';
            }
            SafeNativeMethods.dtrsm(cside, cuplo, tranA, cdiag, m, n, alpha, a, lda, b, ldb);
        }

        public void Zgemm(BlasOrderType order, BlasTransType transA, BlasTransType transB, int m, int n, int k, Complex alpha, Complex[] a, int lda, Complex[] b, int ldb, Complex beta, Complex[] c, int ldc)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char tranB = 'N';
            if (transB == BlasTransType.Trans)
            {
                tranB = 'T';
            }
            else if (transB == BlasTransType.ConjTrans)
            {
                tranB = 'C';
            }
            SafeNativeMethods.zgemm(tranA, tranB, m, n, k, ref alpha, a, lda, b, ldb, ref beta, c, ldc);
        }

        public void Zsymm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, Complex alpha, Complex[] a, int lda, Complex[] b, int ldb, Complex beta, Complex[] c, int ldc)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cside = 'L';
            if (side == BlasSideType.Right)
            {
                cside = 'R';
            }
            SafeNativeMethods.zsymm(cside, cuplo, m, n, ref alpha, a, lda, b, ldb, ref beta, c, ldc);
        }

        public void Zsyrk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, Complex alpha, Complex[] a, int lda, Complex beta, Complex[] c, int ldc)
        {
            char tran = 'N';
            if (trans == BlasTransType.Trans)
            {
                tran = 'T';
            }
            else if (trans == BlasTransType.ConjTrans)
            {
                tran = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zsyrk(cuplo, tran, n, k, ref alpha, a, lda, ref beta, c, ldc);
        }

        public void Zsyr2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, Complex alpha, Complex[] a, int lda, Complex[] b, int ldb, Complex beta, Complex[] c, int ldc)
        {
            char tran = 'N';
            if (trans == BlasTransType.Trans)
            {
                tran = 'T';
            }
            else if (trans == BlasTransType.ConjTrans)
            {
                tran = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zsyr2k(cuplo, tran, n, k, ref alpha, a, lda, b, ldb, ref beta, c, ldc);
        }

        public void Ztrmm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, Complex alpha, Complex[] a, int lda, Complex[] b, int ldb)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }

            char cside = 'L';
            if (side == BlasSideType.Right)
            {
                cside = 'R';
            }
            SafeNativeMethods.ztrmm(cside, cuplo, tranA, cdiag, m, n, ref alpha, a, lda, b, ldb);
        }

        public void Ztrsm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, Complex alpha, Complex[] a, int lda, Complex[] b, int ldb)
        {
            char tranA = 'N';
            if (transA == BlasTransType.Trans)
            {
                tranA = 'T';
            }
            else if (transA == BlasTransType.ConjTrans)
            {
                tranA = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cdiag = 'N';
            if (diag == BlasDiagType.Unit)
            {
                cdiag = 'U';
            }

            char cside = 'L';
            if (side == BlasSideType.Right)
            {
                cside = 'R';
            }
            SafeNativeMethods.ztrsm(cside, cuplo, tranA, cdiag, m, n, ref alpha, a, lda, b, ldb);
        }

        public void Zhemm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, Complex alpha, Complex[] a, int lda, Complex[] b, int ldb, Complex beta, Complex[] c, int ldc)
        {
            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }

            char cside = 'L';
            if (side == BlasSideType.Right)
            {
                cside = 'R';
            }
            SafeNativeMethods.zhemm(cside, cuplo, m, n, ref alpha, a, lda, b, ldb, ref beta, c, ldc);
        }

        public void Zherk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, double alpha, Complex[] a, int lda, double beta, Complex[] c, int ldc)
        {
            char tran = 'N';
            if (trans == BlasTransType.Trans)
            {
                tran = 'T';
            }
            else if (trans == BlasTransType.ConjTrans)
            {
                tran = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zherk(cuplo, tran, n, k, alpha, a, lda, beta, c, ldc);
        }

        public void Zher2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, Complex alpha, Complex[] a, int lda, Complex[] b, int ldb, double beta, Complex[] c, int ldc)
        {
            char tran = 'N';
            if (trans == BlasTransType.Trans)
            {
                tran = 'T';
            }
            else if (trans == BlasTransType.ConjTrans)
            {
                tran = 'C';
            }

            char cuplo = 'U';
            if (uplo == BlasUpLoType.Lower)
            {
                cuplo = 'L';
            }
            SafeNativeMethods.zher2k(cuplo, tran, n, k, ref alpha, a, lda, b, ldb, beta, c, ldc);
        }

        #endregion Public Members
    }
}